package com.elitel.frame.business.aspect;

import com.alibaba.fastjson.JSONObject;
import com.elitel.common.utils.RedisUtils;
import com.elitel.common.utils.StringUtils;
import com.elitel.frame.main.entity.SysPrjservice;


import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;


/**
 * @author m
 */
public class ReqLogUtils {
    public static final String SYS_LOG_COUNT = "dscloud:reqstat:cache:count:";
    public static final String SYS_LOG_ERROR = "dscloud:reqstat:error:";
    public static final String SYS_LOG_SUCCESS = "dscloud:reqstat:success:";
    public final static String FREQUENCY = "F";
    public static final String SYS_LOG_RECENT = "dscloud:reqstat:recent";
    public static final String SERVER_INFO_KEY = "dscloud:config:serverinfo";
    /**
     * 服务请求超时
     */
    public static final String TIMEOUT_MSG = "服务请求超时";
    /**
     * 时间格式化
     */
    public final static String YMD = "yyyyMMdd";

    public static void cacheLog(SysPrjservice sysPrjservice, String appCode, long costTime, String errorMsg, String bodyStr, String path) {
        String serviceCode = sysPrjservice.getServicecode();
        // 生成缓存key
        String appCodeCacheKey = genAppCodeCacheKey(appCode, new Date());
        // 计数
        RedisUtils.zIncrementScore(appCodeCacheKey, serviceCode, 1);
        // 设置过期时间
        RedisUtils.expire(appCodeCacheKey, 10, TimeUnit.DAYS);
        // 失败成功状态
        String status = StringUtils.isNotEmpty(errorMsg) ? "0" : "1";
        // 其他信息
        HashMap<String, String> otherInfoMap = new HashMap<>();
        otherInfoMap.put("serviceCode", serviceCode);
        otherInfoMap.put("serviceName", sysPrjservice.getServicename());
        otherInfoMap.put("serviceType", sysPrjservice.getServicetype());
        otherInfoMap.put("costTime", costTime + "");
        otherInfoMap.put("reqTime", System.currentTimeMillis() + "");
        otherInfoMap.put("status", status);
        otherInfoMap.put("errorMsg", errorMsg);
        if (TIMEOUT_MSG.equals(errorMsg)) {
            otherInfoMap.put("timeoutFlag", "1");
        } else {
            otherInfoMap.put("timeoutFlag", "0");
        }
        otherInfoMap.put("apiPath", sysPrjservice.getApiPath());
        otherInfoMap.put("requestPath", path);
        otherInfoMap.put("reqParam", bodyStr);
        otherInfoMap.put("appCode", appCode);
        // 缓存信息
        RedisUtils.zAdd(SYS_LOG_RECENT, JSONObject.toJSONString(otherInfoMap), System.currentTimeMillis());
        statSuccessOrError(serviceCode, errorMsg);
    }


    private static void statSuccessOrError(String serviceCode, String errorMsg) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat hour = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = simpleDateFormat.format(new Date());
        String dateTime = hour.format(new Date());
        String redisKey;
        if (StringUtils.isNotEmpty(errorMsg)) {
            redisKey = SYS_LOG_ERROR + serviceCode;
        } else {
            redisKey = SYS_LOG_SUCCESS + serviceCode;
        }
        // 异常
        Object o = RedisUtils.hGet(redisKey, date);
        if (o == null) {
            RedisUtils.hPut(redisKey, date, 1 + FREQUENCY + dateTime);
        } else {
            RedisUtils.delete(redisKey);
            String oStr = o + "";
            String[] split = oStr.split(FREQUENCY);
            RedisUtils.hPut(redisKey, date, Integer.parseInt(split[0]) + 1 + FREQUENCY + dateTime);
        }

    }

    private static String genAppCodeCacheKey(String appCode, Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(YMD);
        String format = sdf.format(date);
        try {
            date = sdf.parse(format);
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException("时间解析异常");
        }
        // 放在缓存里面
        return SYS_LOG_COUNT + sdf.format(date) + ":" + appCode;
    }
}
